home *** CD-ROM | disk | FTP | other *** search
- /****** axuucp/ax2uucp *******************************************************
- *
- * NAME
- * ax2uucp - Create UUCP batches from unread AXsh news articles
- *
- * SYNOPSIS
- * rx ax2uucp.rexx [user]
- *
- * DESCRIPTION
- * ax2uucp looks at the user's ~/.rnnewsrc file, collects all unread
- * news articles, joins them together in one ore more UUCP batches
- * and marks these articles as read in user's ~/.rnnewsrc file.
- * If there is pending mail for the given user, ax2uucp creates the
- * spoolfiles for the mail as well and removes it from the system
- * mailbox.
- *
- * The user must have a ~user/.rnnrewsrc file. Otherwise no news
- * articles will be exported. It is recommended that the user
- * subscribes newsgroups via rn. Only articles of subscribed groups
- * will be exported of course.
- *
- * NOTES
- * The created spool files get the following UUCP priorities:
- *
- * News batches D.<system>B<seq>
- * Mail D.<system>A<seq>
- * Control files C.<system>N<seq>
- * Command files D.<system>X<seq>
- *
- * BUGS
- * List LFORMAT "%l" returns text (e.g. "empty" instead of "0") in
- * some situations. Due to localization problems we decided to treat
- * all files with non-digit characters in it's file size like empty
- * files and ignore them.
- *
- * AUTHOR
- * Tobias Ferber <tf@ganymed.hall.sub.org>
- * The mbox scanner and genseq() are Copyright (c)1994 by Tobias Walter
- *
- ******************************************************************************
- *
- */
-
- if (arg() < 1) | (words(arg(1)) < 1) then do
- say 'usage: rx ax2uucp.rexx [user]'
- exit
- end
-
- username = arg(1)
-
- newsrc = axconfig("home") || username || "/.rnnewsrc"
- newsrc_ = newsrc'_'
- axnews = axconfig("news")
- tempfile = axconfig("tempdir") || "ax2uuccp." || pragma('Id')
-
- spooldir = strfmt(axconfig("axuucp.spooldir"),"%u",username)
- seqfile = axconfig("axuucp.seqfile")
-
- bpb_max = axconfig("axuucp.batchlimit"); if words(bpb_max) < 1 then bpb_max=65535
- bpb = 0 /* #of bytes per batch */
-
- axmail = axconfig("mail")
- aka = axconfig("thismachine")
- nodename = aka; p=pos('.',nodename); if p>1 then nodename=left(nodename,p-1)
- mbox = axmail || username
- toaddr = username /*'@'aka*/
-
- xmail = 0 /* #of exported mail messages */
- xnews = 0 /* #of exported news articles */
-
- /**/
-
- if ~exists(axnews) | ~exists(axmail) | (words(nodename) < 1) then do
- say 'ax2uucp: Error in "/etc/rc" (%mail:, %news: or %thismachine:)'
- exit 10
- end
-
- if ~exists(spooldir) then do
- say 'ax2uucp: No such spool directory: "'spooldir'"'
- exit 10
- end
-
-
- /* News */
-
- if exists(newsrc_) then address command 'Delete QUIET "'newsrc_'"'
-
- if open('rc',newsrc,'Read') then do
-
- do until eof('rc')
- str= readln('rc')
- if words(str) > 0 then do
- parse var str lhs ' ' rhs
- gflag= right(lhs,1) /* ':' = subscribed, '!' = unsubscribed */
- gname= left(lhs,length(lhs)-1)
- gdir= axnews || translate(gname,'/','.')
- gex=0 /* #of articles exported for this group */
-
- if gflag = ':' then do
- if exists(gdir'/.lowest') & exists(gdir'/.next') then do
- call open('seq',gdir'/.lowest','Read'); glowest= readln('seq'); call close('seq')
- call open('seq',gdir'/.next','Read'); gnext= readln('seq'); call close('seq')
-
- address command 'List FILES DIR "'gdir'" LFORMAT "%n(%l)" PAT "~(.#?)" > "'tempfile'"'
- call open('tmp',tempfile,'Read')
- do until eof('tmp')
- art= readln('tmp')
- if words(art) > 0 then do
- parse var art artno '(' bpa ')'
- if words(compress(bpa,"0123456789")) > 0 then bpa=0
- if (bpa>0) & ~inset(artno,rhs) then do
- if (bpb=0) | ((bpb+bpa+18)>bpb_max) then do
- if bpb>0 then bpb= spool_news(tempbatch,seq)
- seq = genseq(seqfile)
- tempbatch = spooldir || spoolfile('D',nodename,'B',seq) || ".TMP";
- end
- address command 'Echo >> "'tempbatch'"' || '"#! rnews' right(bpa,8,'0')'"'
- address command 'Type >> "'tempbatch'"' || '"'gdir'/'artno'"' /* unset NOCLOBBER ! */
- bpb = bpb + 18 + bpa /* 18 bytes "#! rnews 00000000\n" */
- gex=gex+1
- end
- end
- end
- call close('tmp')
-
- address command 'Delete QUIET FILE "'tempfile'"'
- rhs="0"
- if (gnext>0) & (gnext>glowest+1) then rhs= rhs'-'gnext-1
- /*say gname || gflag rhs 'of' gnext-glowest 'in ['glowest'..'gnext-1'], exported:' gex*/
- xnews= xnews+gex
- end
-
- else do
- say 'Newsgroup "'gname'" not available -- will be unsubscribed'
- gflag= '!'
- end
-
- end
- address command 'Echo >> "'newsrc_'"' '"'gname || gflag rhs'"'
- end
- end
-
- call close('rc')
- address command 'Copy QUIET FROM "'newsrc_'" TO "'newsrc'"'
- address command 'Delete QUIET FILE "'newsrc_'"'
- if bpb>0 then bpb= spool_news(tempbatch,seq)
- end
-
- else do
- say 'ax2uucp: user' username 'has no ~/.rnnewsrc'
- end
-
-
- /* Mail */
-
- if exists(mbox) then do
- if open('in',mbox,'Read') then do
- l = readln('in')
- state='start';
-
- do while ~eof('in')
- select
-
- when state = 'start' then do
- if word(l,1)~='From' then do
- say 'From_ expected in line 1'
- exit 20
- end
- else do
- orig = l
- state = 'next'
- end
- end
-
- when state = 'next' then do
- call open('fp',tempfile,'Write')
- call writeln('fp',orig) /* From_ */
- /*if upper(left(l,4)) = 'TO: ' then toaddr= rfcaddr(substr(l,5))*/
- /*else*/ if l='' then state='body null'
- call writeln('fp',l)
- state = 'header'
- end
-
- when state = 'header' then do
- /*if upper(left(l,4)) = 'TO: ' then toaddr= rfcaddr(substr(l,5))*/
- /*else*/ if l='' then state='body null'
- call writeln('fp',l)
- end
-
- when state = 'body null' then do
- if word(l,1)='From' then do
- orig = l
- state = 'body from'
- end
- else do
- call writeln('fp',l)
- if l~='' then state = 'body nonnull'
- end
- end
-
- when state = 'body from' then do
- if right(word(l,1),1)=':' then do
- call close('fp')
- call spool_mail(tempfile,genseq(seqfile),toaddr)
- /*toaddr= username'@'aka*/
- xmail= xmail+1
- state= 'have next'
- end
- else do
- call writeln('fp',orig)
- call writeln('fp',l)
- if l='' then state = 'body null'
- else state = 'body nonull'
- end
- end
-
- when state = 'body nonnull' then do
- call writeln('fp',l)
- if l='' then state = 'body null'
- end
-
- otherwise nop
- end
-
- if state = 'have next' then state = 'next'
- else l= readln('in')
- end
-
- call close('in')
-
- if word(state,1) = 'body' then do
- call close('fp')
- call spool_mail(tempfile,genseq(seqfile),toaddr)
- xmail= xmail+1
- end
-
- if exists(tempfile) then address command 'Delete QUIET "'tempfile'"'
- address command 'Delete QUIET "'mbox'"'
- end
-
- else do
- say 'ax2uucp: could not read system mbox for user "'username'"'
- end
- end
-
- /*
- else do
- say 'ax2uucp: no pending mail for user' username
- end
- */
-
- say 'ax2uucp: export for user "'username'":' xmail 'mail message(s),' xnews 'news article(s)'
- exit
-
-
- /*
- */
-
-
- /* find out whether an article is member of a set of articles */
-
- inset: procedure
- arg n,set
- do while words(set) > 0
- parse var set r ',' set
- if pos('-',r) > 0 then do
- parse var r r0 '-' r1
- if ((r0 <= n) & (n <= r1)) then return 1
- end
- else if r=n then return 1
- end
- return 0
-
-
- /* return the name of a spoolfile */
-
- spoolfile: procedure
- parse arg type,node,pri,seq
- return upper(left(type,1)) || "." || left(node,min(length(node),7)) || upper(left(pri,1)) || seq
-
-
- /* create the spoolfiles for an uncompressed news batchfile */
-
- spool_news: procedure expose username nodename spooldir
- parse arg fname,seq
-
- dname_here = spoolfile('D',username,'B',seq); dname_there = spoolfile('D',nodename,'B',seq)
- xname_here = spoolfile('D',username,'X',seq); xname_there = spoolfile('X',nodename,'B',seq)
-
- dfile = spooldir || dname_here;
- xfile = spooldir || xname_here
- cfile = spooldir || spoolfile('C',username,'N',seq)
-
- address command 'cat < "'fname'" > "'dfile'"'
- /*address command 'compress -c < "'fname'" > "'dfile'"'*/
- address command 'Delete QUIET FILE "'fname'"'
-
- address command 'Echo > "'xfile'" "' || 'U news' nodename || '*N' ||,
- 'R postmaster' || '*N' ||,
- 'Z' || '*N' ||,
- 'F' dname_there || '*N' ||,
- 'I' dname_there || '*N' ||,
- 'C rnews' || '"'
-
- address command 'Echo > "'cfile'" "' || 'S' dname_here dname_there 'root' '-' dname_here '0666' || '*N' ||,
- 'S' xname_here xname_there 'root' '-' xname_here '0666' || '"'
-
- return 0
-
-
- /* create the spoolfiles for a mailfile */
-
- spool_mail: procedure expose username nodename spooldir
- parse arg fname,seq,toaddr
-
- dname_here = spoolfile('D',username,'B',seq); dname_there = spoolfile('D',nodename,'B',seq)
- xname_here = spoolfile('D',username,'X',seq); xname_there = spoolfile('X',nodename,'B',seq)
-
- dfile = spooldir || dname_here;
- xfile = spooldir || xname_here
- cfile = spooldir || spoolfile('C',username,'N',seq)
-
- address command 'Copy QUIET CLONE FROM "'fname'" TO "'dfile'"'
- address command 'Delete QUIET FILE "'fname'"'
-
- address command 'Echo > "'xfile'" "' || 'U daemon' nodename || '*N' ||,
- 'R postmaster' || '*N' ||,
- 'Z' || '*N' ||,
- 'F' dname_there || '*N' ||,
- 'I' dname_there || '*N' ||,
- 'C rmail' nodename || '"'
-
- address command 'Echo > "'cfile'" "' || 'S' dname_here dname_there 'root' '-' dname_here '0666' || '*N' ||,
- 'S' xname_here xname_there 'root' '-' xname_here '0666' || '"'
- return 0
-
-
-
- /*@<genseq><axconfig><strfmt>*/
-
- /* from `mbox2ums.rexx' by Tobias Walter */
-
- genseq: procedure
- parse arg seqfile
-
- call open('seq',seqfile,'Read')
- seq= readln('seq')
- call close('seq')
-
- if seq>1679616 then seq=1 /* 1679616 = 36*36*36*36 */
-
- call open('seq',seqfile,'Write')
- call writeln('seq',seq+1)
- call close('seq')
-
- uuseq= ""
- do i=0 to 3
- c= seq//36; seq= seq%36 /* 36 = [0-9]+[a-z] */
- if c>=10 then c= d2c(c+87) /* 87 = c2d('a')-10 */
- uuseq= c || uuseq
- end
-
- return uuseq
-
-
- /* get an AXsh configuration value */
-
- axconfig: procedure
- tempfile = "T:axconfig." || pragma('Id')
- rc_index = "AXsh:rexx/rc.index"
- var_val=""; var_file=""; var_defval="";
-
- parse upper arg var_name
- if left(var_name,1) ~= '%' then var_name = '%'var_name
- if right(var_name,1) ~= ':' then var_name = var_name':'
-
- if open('idx',rc_index,'Read') then do
- do until (eof('idx') | (var_file~=''))
- str= translate(readln('idx'),' ',d2c(9))
- if words(str) > 0 then do
- parse var str vname ' ' fname '"' defval '"'
- if upper(vname) = var_name then do
- var_file= strip(fname,'B',' 'd2c(9))
- var_defval= defval
- end
- end
- end
- call close('idx')
- end
- else say 'Could not read "'rc_index'"'
-
- if words(var_file) > 0 then do
- if open('rc',var_file,'Read') then do
- do until (eof('rc') | (var_val~=''))
- str= translate(readln('rc'),' ',d2c(9))
- if upper(word(str,1)) = var_name then var_val = strip(readln('rc'),'B',' 'd2c(9))
- end
- call close('rc')
- end
- else say 'Could not examine "'var_file'" for' var_name
- end
- else do
- if words(var_defval) > 0 then var_val= var_defval
- else say 'No such config variable:' var_name
- end
-
- return var_val
-
-
- /* substitute all occurences of 'fmt' in 'str' by 'val' */
-
- strfmt: procedure
- parse arg str,fmt,val
- p= pos(fmt,str)
- do while p>0
- str= left(str,p-1) || val || substr(str,p+length(fmt))
- p= pos(fmt,str)
- end
- return str
-
-
-